package cn.bugstack.domain.strategy.service;

import cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity;
import cn.bugstack.domain.strategy.model.entity.RaffleFactoryEntity;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.vo.RuleLogicCheckTypeVO;
import cn.bugstack.domain.strategy.model.vo.StrategyAwardRuleModelVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.armory.IStrategyDispatch;
import cn.bugstack.domain.strategy.service.rule.chain.ILogicChain;
import cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory;
import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import cn.bugstack.types.enums.ResponseCode;
import cn.bugstack.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * 抽奖策略抽象类
 */
@Slf4j
public abstract class AbstractRaffleStrategy implements IRaffleStrategy {

    protected IStrategyRepository repository;

    protected IStrategyDispatch strategyDispatch;

    protected final DefaultChainFactory defaultChainFactory;

    protected final DefaultTreeFactory defaultTreeFactory;

    public AbstractRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch, DefaultChainFactory defaultChainFactory, DefaultTreeFactory defaultTreeFactory) {
        this.repository = repository;
        this.strategyDispatch = strategyDispatch;
        this.defaultChainFactory = defaultChainFactory;
        this.defaultTreeFactory = defaultTreeFactory;
    }

//    public AbstractRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch, DefaultTreeFactory defaultTreeFactory) {
//        this.defaultTreeFactory = defaultTreeFactory;
//        if (repository == null || strategyDispatch == null) {
//            throw new IllegalArgumentException("repository and strategyDispatch cannot be null");
//        }
//        this.repository = repository;
//        this.strategyDispatch = strategyDispatch;
//    }

    @Override
    public RaffleAwardEntity performRaffle(RaffleFactoryEntity raffleFactoryEntity) {
        //1. 参数校验
        String userId = raffleFactoryEntity.getUserId();
        Long strategyId = raffleFactoryEntity.getStrategyId();
        if (strategyId == null || StringUtils.isBlank(userId)) {
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
        }

//        // 2.责任链处理抽奖
//        ILogicChain logicChain = defaultChainFactory.openLogicChain(strategyId);
//
//        // 3. 通过责任链获取奖品ID
//        DefaultChainFactory.StrategyAwardVO strategyAwardVO = logicChain.logic(userId, strategyId);
//        Integer awardId = strategyAwardVO.getAwardId();
//
//        // 4. 查询奖品规则 抽奖中、 抽奖后
//        StrategyAwardRuleModelVO strategyAwardRuleModelVO = repository.queryStrategyAwardRuleModel(strategyId, awardId);

//        // 4.抽奖中 - 规则过滤
//        this.doCheckRaffleCenterLogic(RaffleFactoryEntity.builder()
//                .userId(userId)
//                .strategyId(strategyId)
//                .awardId(awardId)
//                .build(), strategyAwardRuleModelVO.raffleCenterRuleModelList());
//
//        //5. 查询奖品规则， 抽奖中，拿到奖品ID时过滤规则、 抽奖后（扣减完奖品库存后过滤，抽奖中拦截和无库存则走兜底）
//        StrategyAwardRuleModelVO strategyAwardRuleModelVO = repository.queryStrategyAwardRuleModel(strategyId, awardId);


//        //4. 抽奖中 - 规则过滤
//        RuleActionEntity<RuleActionEntity.RaffleCenterEntity> ruleActionCenterEntity = this.doCheckRaffleCenterLogic(RaffleFactoryEntity.builder()
//                .userId(userId)
//                .strategyId(strategyId)
//                .awardId(awardId)
//                .build(), strategyAwardRuleModelVO.raffleCenterRuleModelList());
//
//        if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionCenterEntity.getCode())) {
//            log.info("【临时日志】中奖中规则拦截，通过抽奖后规则rule_luck_award走兜底奖励。");
//            return RaffleAwardEntity.builder()
//                    .awardDesc("中奖中规则拦截，通过抽奖后规则rule_luck_award走兜底奖励。")
//                    .build();
//        }

        // 2. 责任链抽奖计算 初步抽奖ID， 后续根据ID处理抽奖 黑名单、权重等非默认抽奖的直接返回抽奖结果
        DefaultChainFactory.StrategyAwardVO chainStrategyAwardVO = raffleLogicChain(userId, strategyId);
        log.info("抽奖策略计算-责任链 {} {} {} {}", userId, strategyId, chainStrategyAwardVO.getAwardId(), chainStrategyAwardVO.getLogicModel());
        if (!DefaultChainFactory.LogicModel.RULE_DEFAULT.getCode().equals(chainStrategyAwardVO.getLogicModel())) {
            return RaffleAwardEntity.builder()
                    .awardId(chainStrategyAwardVO.getAwardId())
                    .build();
        }

        // 3. 规则树抽奖过滤 奖品ID， 根据抽奖次数、库存和兜底返回最终的可获得奖品信息
        DefaultTreeFactory.StrategyAwardVO treeStrategyAwardVO = raffleLogicTree(userId, strategyId, chainStrategyAwardVO.getAwardId());
        log.info("抽奖策略-规则树 {} {} {} {}", userId, strategyId,treeStrategyAwardVO.getAwardId(), treeStrategyAwardVO.getAwardRuleValue());


        return RaffleAwardEntity.builder()
                .awardId(treeStrategyAwardVO.getAwardId())
                .awardConfig(treeStrategyAwardVO.getAwardRuleValue())
                .build();

    }

    public abstract DefaultChainFactory.StrategyAwardVO raffleLogicChain(String userId, Long strategyId);

    public abstract DefaultTreeFactory.StrategyAwardVO raffleLogicTree(String userId, Long strategyId, Integer awardId);


}
